package network_programming.np1_socket_and_serversocket;

import multithreading.ThreadPool;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 利用自定义线程池ThreadPool来完成与客户端的通信任务
 * ThreadPool在multithreading包下
 *
 *
 * Runtime类
 * 每个Java应用程序都有一个类Runtime的实例，允许应用程序通过该类实例与运行应用程序的环境进行交互。
 * 当前运行时的Runtime对象可以从getRuntime方法获得。
 * 应用程序本身不能创建该类的实例
 * 
 * private static Runtime currentRuntime = new Runtime();
 * 
 * public static Runtime getRuntime() {		// 返回与当前Java应用关联的runtime对象
 * 		return currentRuntime;
 * }
 * 大多数Runtime类的方法是实例方法，所以必须被调用与具体的当前运行时对象。
 * 
 * public native int availableProcessors()			返回Java虚拟机可用的处理器数
 * Runtime.getRuntime().availableProcessors()       获取Java虚拟机可用的处理器（CUP）数量
 * 
 * public Process exec(String command) throws IOException {	// 在一个单独的进程中执行指定的命令
 * 		return exec(command, null, null);
 * }
 * */
public class EchoServerThreadPool {
    private int port = 9099;        // 监听的端口号
    private final ServerSocket serverSocket;
    private ThreadPool threadPool;  // 线程池
    private final int POOL_SIZE = 4;    // 单个CUP时线程池中工作线程的数目

    public EchoServerThreadPool() throws IOException {
        serverSocket = new ServerSocket(port);
        threadPool = new ThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);
        System.out.println("服务器已启动");
    }
    
    public void service() {
        while(true) {
            try {
                Socket socket = serverSocket.accept();
                threadPool.execute(new EchoServerHandler(socket));		// 把与客户通信的任务交给线程池
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
		new EchoServerThreadPool().service();
	}
}
